<?php

namespace Fluency\Utils;

/**
 * A callable function object class which can be used for autoloading. It assigns a directory to a
 * namespace and includes files from that directory when classes from the specified namespace are
 * requested. For example, if the Fluency namespace maps to the directory /dir, then the
 * file name corresponding to the class Fluency\Utils\ClassLoader is /dir/Utils/ClassLoader.php.
 *
 * @package Fluency\Utils
 * @author  Ignas Rudaitis
 * @version 2.0.0
 */
class ClassLoader
{
    const GLOBAL_NAMESPACE = "";

    private $namespace;
    private $dir;
    private $extension;

    /**
     * The constructor.
     *
     * @param string $namespace the namespace to assign to the given directory
     * @param string $dir the directory to assign the given directory to
     * @param string $extension the extension to append to class file names
     */
    public function __construct($namespace, $dir, $extension = ".php")
    {
        $this->namespace = ltrim($namespace, "\\");
        $this->dir = $dir;
        $this->extension = $extension;
    }

    /**
     * Tries to include the file corresponding to the given class name.
     *
     * @param string $class
     */
    public function __invoke($class)
    {
        if ($this->namespace === "" || strpos($class, $this->namespace . "\\") === 0) {
            $class = strtr(ltrim($class, "\\"), "\\", DIRECTORY_SEPARATOR);
            if ($this->namespace !== static::GLOBAL_NAMESPACE) {
                $class = substr($class, strlen($this->namespace) + strlen(DIRECTORY_SEPARATOR));
            }
            $file = $this->dir . DIRECTORY_SEPARATOR . $class . $this->extension;
            if (is_readable($file)) {
                require_once $file;
            }
        }
    }
}
